package com.cloudbroker.bcs.platform.ltb.middle.util;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.Map.Entry;

import com.alibaba.fastjson.JSON;
import com.cloudbroker.bcs.platform.ltb.bizapi.service.user.back.UsersQueryVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.config.RequestConfig.Builder;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.cloudbroker.bcs.platform.ltb.common.extservice.store.StoreServiceFactory;
import com.cloudbroker.bcs.platform.ltb.middle.constants.HttpConstant;

/**
 * Created by wangxu13798 on 2016/3/15.
 */
public class HttpUtil {
	
	private static final Logger LOG = LoggerFactory
			.getLogger(HttpUtil.class);
	
    private static final CloseableHttpClient httpClient;
    public static final String CHARSET = "UTF-8";
	private static final RequestConfig config;
    static {
         config = RequestConfig.custom().setConnectTimeout(60000).setSocketTimeout(15000).build();
        httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).build();
    }

    public static String doGet(String url, Map<String, Object> params){
        return doGet(url, params,CHARSET);
    }
    public static String doPost(String url, Map<String, Object> params){
        return doPost(url, params,CHARSET);
    }
    /**
     * HTTP Get 获取内容
     * @param url  请求的url地址 ?之前的地址
     * @param params 请求的参数
     * @param charset    编码格式
     * @return    页面内容
     */
    public static String doGet(String url, Map<String,Object> params, String charset){
        if(StringUtils.isBlank(url)){
            return null;
        }
        try {
            List<NameValuePair> pairs = mapToList(params);
            if(params != null && !params.isEmpty()){
                url += "?" + EntityUtils.toString(new UrlEncodedFormEntity(pairs, charset));
            }
            HttpGet httpGet = new HttpGet(url);
            CloseableHttpResponse response = httpClient.execute(httpGet);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpGet.abort();
                throw new RuntimeException("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null){
                result = EntityUtils.toString(entity, "utf-8");
            }
			LOG.info("\r\n"+new Date().toString()+"--");
			LOG.info(result+"\r\n");
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * HTTP Post 获取内容
     * @param url  请求的url地址 ?之前的地址
     * @param params 请求的参数
     * @param charset    编码格式
     * @return    页面内容
     */
    public static String doPost(String url,Map<String,Object> params,String charset){
        if(StringUtils.isBlank(url)){
            return null;
        }
        try {
            List<NameValuePair> pairs = mapToList(params);
            HttpPost httpPost = new HttpPost(url);
            if(pairs != null && pairs.size() > 0){
                httpPost.setEntity(new UrlEncodedFormEntity(pairs,CHARSET));
            }
            CloseableHttpResponse response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpPost.abort();
                throw new RuntimeException("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null){
                result = EntityUtils.toString(entity, "utf-8");
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    public static String sendPost(String url, Map<String, String> params,
			String charSet, String charsetReturn, HttpHost proxy,
			String authorization, String interfacename) {
		try {
			HttpPost post = new HttpPost(url);
			Builder builder = RequestConfig.custom();
			if (proxy != null) {
				builder.setProxy(proxy);
				RequestConfig requestConfig = builder
						.setSocketTimeout(HttpConstant.SOCKET_TIMEOUT)
						.setConnectTimeout(HttpConstant.CONNECT_TIMEOUT)
						.setConnectionRequestTimeout(HttpConstant.REQUEST_TIMEOUT)
						.setExpectContinueEnabled(false)
						.setRedirectsEnabled(true).build();
				post.setConfig(requestConfig);
			}

			post.setHeader("Content-Type", HttpConstant.CONTENT_TYPE_FORM);
			post.setHeader("Authorization", authorization);
			List<NameValuePair> nvps = new ArrayList<NameValuePair>();
			StringBuffer sb = new StringBuffer();
			if (params != null) {
				int n = 0;
				for (Entry<String, String> set : params.entrySet()) {
					if (n == 0) {
						n++;
						sb.append(set.getKey() + "=" + set.getValue());
					} else {
						sb.append("&" + set.getKey() + "=" + set.getValue());
					}
					nvps.add(new BasicNameValuePair(set.getKey(), set
							.getValue()));
				}
			}
			post.setEntity(new UrlEncodedFormEntity(nvps, charSet));
			LOG.info("post  url = [" + (url.endsWith("?") ? url : url + "?")
					+ sb.toString() + "]");
			HttpResponse response = httpClient.execute(post);
			int status = response.getStatusLine().getStatusCode();
			HttpEntity entity = null;
			try {
				entity = response.getEntity();
				if (entity != null) {
					String result = EntityUtils.toString(entity, charsetReturn);
					LOG.info(interfacename + "result = " + result);
					return result;
				}
			} catch (Exception e) {
				LOG.info("HttpClient   请求 http状态码 status = [" + status
						+ "]  获取HttpEntity ");
			} finally {
				if (entity != null) {
					entity.getContent().close();
				}
			}
		} catch (ClientProtocolException e) {
			LOG.info("HttpClient   请求  ClientProtocolException ");
		} catch (IOException e) {
			LOG.info("HttpClient   请求  IOException ");
		}
		return null;
	}
    
    public static String sendGet(String url, Map<String, String> params,
			String charSet, HttpHost proxy, String authorization,String interfacename) {
		try {
			StringBuffer urlbuf = new StringBuffer(url);
			if (params != null) {
				int n = 0;
				for (Entry<String, String> set : params.entrySet()) {
					if (!urlbuf.toString().contains("?")) {
						urlbuf.append("?");
					}
					if (n != 0) {
						urlbuf.append("&");
					}
					urlbuf.append(set.getKey()).append("=")
							.append(set.getValue());
					n++;
				}
			}
			LOG.info("get = " + urlbuf.toString());
			HttpGet get = new HttpGet(urlbuf.toString());
			get.setHeader("Content-Type", HttpConstant.CONTENT_TYPE_FORM);
			get.setHeader("Authorization", authorization);
			// HttpUriRequest get = new HttpGet(urlbuf.toString());
			Builder builder = RequestConfig.custom();
			if (proxy != null) {
				builder.setProxy(proxy);
			}

			RequestConfig defaultConfig = builder
					.setSocketTimeout(HttpConstant.SOCKET_TIMEOUT)
					.setConnectTimeout(HttpConstant.CONNECT_TIMEOUT)
					.setConnectionRequestTimeout(HttpConstant.REQUEST_TIMEOUT)
					.setExpectContinueEnabled(false).setRedirectsEnabled(true)
					.build();
			get.setConfig(defaultConfig);

			HttpResponse response = httpClient.execute(get);

			int status = response.getStatusLine().getStatusCode();
			HttpEntity entity = null;
			try {
				entity = response.getEntity();
				if (entity != null) {
					String result=EntityUtils.toString(entity, charSet);
					LOG.info(interfacename+"result = " + result);
					return result;
				}
			} catch (Exception e) {
				e.printStackTrace();
				LOG.info("HttpClient   请求 http状态码 status = [" + status
						+ "]  ");
			} finally {
				if (entity != null) {
					entity.getContent().close();
				}
			}
		} catch (ClientProtocolException e) {
			LOG.info("HttpClient   请求  ClientProtocolException ");
		} catch (IOException e) {
			LOG.info("HttpClient   请求  IOException ");
		}
		return null;
	}

    private static List<NameValuePair> mapToList(Map<String,Object> params){
        List<NameValuePair> pairs = new ArrayList<NameValuePair>(params.size());
        if(params != null && !params.isEmpty()){
            for(Entry<String,Object> entry : params.entrySet()){
                String value = entry.getValue().toString();
                if(value != null){
                    pairs.add(new BasicNameValuePair(entry.getKey(),value));
                }
            }
        }
        return pairs;
    }

    public static String doXmlPost(String url,String xml){
        HttpPost post = new HttpPost(url);
        try {
            StringEntity entity = new StringEntity(xml);
            post.setEntity(entity);
            post.setHeader("Content-Type", "text/xml;charset=UTF-8");
            CloseableHttpResponse httpResponse = httpClient.execute(post);
			String result = acquireResult(httpResponse,post);
			LOG.info("\r\n"+new Date().toString()+"--");
			LOG.info(result +"\r\n");
            return result;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /***
     * 获取Http Get/Post请求中返回的数据
     * @param response	服务器返回response
     * @param requestBase HttpGet/HttpPost 对象
     *
     * @return String 服务器返回数据
     * */
    private static String acquireResult(CloseableHttpResponse response , HttpRequestBase requestBase) throws IOException {
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode != HttpStatus.SC_OK) {
            requestBase.abort();
            throw new RuntimeException("HttpClient,error status code :" + statusCode);
        }
        HttpEntity entity = response.getEntity();
        String result = null;
        if (entity != null) {
            result = EntityUtils.toString(entity, "utf-8");
        }
        EntityUtils.consume(entity);
        return result;
    }


	/**
	 * 提交json数据
	 *
	 * @param url
	 * @param json
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static String doPostJson(String url, String json) {
		// 创建http POST请求
		HttpPost httpPost = new HttpPost(url);
		httpPost.setConfig(config);
		if (json != null) {
			// 构造一个form表单式的实体
			StringEntity stringEntity = new StringEntity(json, ContentType.APPLICATION_JSON);
			// 将请求实体设置到httpPost对象中
			httpPost.setEntity(stringEntity);
		}
		CloseableHttpResponse response = null;
		try {
			// 执行请求
			response = httpClient.execute(httpPost);
			return acquireResult(response, httpPost);
		} catch (Exception e) {
			e.printStackTrace();
			LOG.error("接口服务器返回值出错，错误码：" + response.getStatusLine().getStatusCode()
					+ "，错误信息：" + e);
		} finally {
			try {
				if (response != null) {
					response.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

		}
		return null;

	}



	public static void main(String[] args) throws  Exception {
		Map<String, String> paramMap = new HashMap<>();
		paramMap.put("user_token","d5aa3e65305e42bcbc85fa0ff7e96ee0");
		paramMap.put("user_ids", "261554,1160");
		paramMap.put("source","cloudbroker_2");
		paramMap.put("sign", genSign("cloudbroker_2","1D30DB23C7477E693FDA62E6CDA3168D"));
		String result = doPostJson("http://10.253.102.179:8022/func_users_query", JSON.toJSONString(paramMap));
		UsersQueryVo usersQueryVo = JSON.parseObject(result,UsersQueryVo.class);
		System.out.println(result);
	}

	public static String genSign(String source,String signKey){
		Map<String, String> map=new HashMap<>();
		map.put("source", source);
		map.put("signKey", signKey);
		return  MD5Util.encrypt(map.toString());
	}
}
